import 'package:flutter/cupertino.dart';

import '../../config/public_color.dart';
import '../../foundation/style/bold_text_style.dart';
import '../container/radius_shadow_container.dart';
import 'index_bar.dart';
import 'model/alphabet_index_model.dart';

/// FileName alphabet_index
///
/// @Author lax
/// @Date 2023/3/27
///
/// @Description

class AlphabetIndex<T> extends StatefulWidget {
  final List<AlphabetIndexModel<T>> dataSource;

  final Widget Function(int section, int index)? itemBuilder;

  final Widget Function(int section, int index)? separatedBuilder;

  final Widget Function(int section)? sectionHeaderBuilder;

  final EdgeInsets? padding;

  final double itemHeight;

  final double separatedHeight;

  final EdgeInsets? sectionPadding;
  final double sectionRadius;
  final double sectionHeaderHeight;

  /// 是否显示字母索引 默认true
  final bool showIndexBar;

  const AlphabetIndex({
    super.key,
    this.dataSource = const [],
    this.itemBuilder,
    this.separatedBuilder,
    this.sectionHeaderBuilder,
    this.padding,
    this.itemHeight = 44,
    this.separatedHeight = 0.5,
    this.sectionPadding,
    this.sectionRadius = 5,
    this.sectionHeaderHeight = 44,
    this.showIndexBar = true,
  });

  @override
  State<StatefulWidget> createState() {
    return _AlphabetIndexState();
  }
}

class _AlphabetIndexState extends State<AlphabetIndex> {
  ScrollController scrollController = ScrollController(keepScrollOffset: false);

  final GlobalKey listKey = GlobalKey();

  // 当前位置
  int currentSection = 0;

  // 内容最大的高度
  double maxContent = 0;

  @override
  void initState() {
    super.initState();
    if (!widget.showIndexBar) {
      return;
    }
    scrollController.addListener(() {
      // 处理滚动事件 设置字母当前位置
      int index = widget.dataSource.indexWhere(
              (element) => scrollController.offset < element.startOffset) -
          1;
      // 处理特殊情况
      if (scrollController.offset >= widget.dataSource.last.startOffset) {
        index = widget.dataSource.length - 1;
      }
      if (index < 0) {
        index = 0;
      }
      if (currentSection != index) {
        setState(() {
          currentSection = index;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    // 初始化每个section的偏移量
    if (widget.dataSource.length > 1 && widget.dataSource[1].startOffset <= 0) {
      double offset = 0;
      if (widget.padding != null) {
        offset += widget.padding?.top ?? 0;
      }

      for (var element in widget.dataSource) {
        element.startOffset = offset;
        if (element.data != null && element.data!.isNotEmpty) {
          element.contentHeight = element.data!.length * widget.itemHeight +
              (element.data!.length - 1) * widget.separatedHeight;
        } else {
          element.contentHeight = 0;
        }

        if (widget.sectionPadding != null) {
          offset += (widget.sectionPadding?.top ?? 0) +
              (widget.sectionPadding?.bottom ?? 0);
        }
        offset += widget.sectionHeaderHeight;
        offset += element.contentHeight;
      }

      if (widget.padding != null) {
        offset += widget.padding?.bottom ?? 0;
      }
    }

    // 计算最大高度
    if (widget.dataSource.isNotEmpty) {
      maxContent = widget.dataSource.last.startOffset +
          widget.dataSource.last.contentHeight;
    }

    return Stack(
      children: [
        ListView.builder(
          physics: const AlwaysScrollableScrollPhysics(),
          padding: widget.padding ?? EdgeInsets.zero,
          key: listKey,
          controller: scrollController,
          itemCount: widget.dataSource.length,
          itemBuilder: (BuildContext context, int section) {
            return Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                widget.sectionHeaderBuilder != null
                    ? widget.sectionHeaderBuilder!(section)
                    : Container(
                        padding: EdgeInsets.symmetric(
                            horizontal: widget.sectionRadius),
                        alignment: Alignment.centerLeft,
                        height: widget.sectionHeaderHeight,
                        child: Text(
                          widget.dataSource[section].alphabet?.toUpperCase() ??
                              '',
                          style: BoldTextStyle(
                              fontSize: 16, color: PublicColor.lightText),
                        ),
                      ),
                RadiusShadowContainer(
                  radius: widget.sectionRadius,
                  padding: widget.sectionPadding ?? const EdgeInsets.all(0),
                  child: sectionListView(section),
                ),
              ],
            );
          },
        ),
        Visibility(
          visible: widget.showIndexBar,
          child: IndexBar(
            selectedIndex: currentSection,
            dataSource: widget.dataSource.map((e) => e.alphabet ?? '').toList(),
            onChanged: (int section, String str) {
              if (currentSection == section) {
                return;
              }
              // 索引变化 计算偏移量
              double offset = widget.dataSource[section].startOffset;
              RenderObject? listBox =
                  listKey.currentContext?.findRenderObject();
              double maxOffset =
                  maxContent - (listBox?.semanticBounds.size.height ?? 0);
              if (maxOffset < 0) {
                maxOffset = 0;
              }
              if (offset > maxOffset) {
                offset = maxOffset;
              }
              scrollController.jumpTo(offset);
              setState(() {
                currentSection = section;
              });
            },
          ),
        ),
      ],
    );
  }

  Widget sectionListView(int section) {
    return ListView.separated(
      shrinkWrap: true,
      padding: EdgeInsets.zero,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: widget.dataSource[section].data?.length ?? 0,
      separatorBuilder: (_, index) {
        if (widget.separatedBuilder == null) {
          return SizedBox(height: widget.separatedHeight);
        }
        return SizedBox(
          height: widget.separatedHeight,
          child: widget.separatedBuilder == null
              ? null
              : widget.separatedBuilder!(section, index),
        );
      },
      itemBuilder: (_, index) {
        if (widget.itemBuilder == null) {
          return SizedBox(height: widget.itemHeight);
        }
        return SizedBox(
          height: widget.itemHeight,
          child: widget.itemBuilder == null
              ? null
              : widget.itemBuilder!(section, index),
        );
      },
    );
  }
}
